package model;

import java.util.Timer;
import java.util.Observable;
import android.graphics.Rect;
import android.util.Log;

public class Holder extends Observable
{
	private static final String TAG = Holder.class.getSimpleName();
	
	// ID can also contain letters
	private String _id;
	
	// surface is the rectangle-area that holds the Qr-code
	private Rect _surface;
	
	private Machine _machine;
	
	// update cycle variables
	private Timer _machineUpdateTimer;
	private static int MACHINE_UPDATE_DELAY = 1000;
	
	private String errorMessage = "";
	
	
	public Holder(String ID, Rect surface, ThreadHandler handler)
	{
		this._surface = surface;
		this._id = ID;
		
		startMachineUpdateCycle(handler);
	}
	
	public String getErrorMessage()
	{
		return errorMessage;
	}
	
	/* 
	 * this method should only be called during construction of Holder or when the application resumes from a pause (onResume)
	 * this method starts the cycle that will call for an update every MACHINE_UPDATE_DELAY milliseconds
	 */
	public void startMachineUpdateCycle(ThreadHandler handler)
	{
		Log.d(TAG, String.format("startMachineCycle()"));
		_machineUpdateTimer = new Timer();
		_machineUpdateTimer.schedule(new UpdateTask(this, handler), MACHINE_UPDATE_DELAY, MACHINE_UPDATE_DELAY);
	}

	// this method is called when the machine object with the latest information is received
	public void updateMachine(Machine machine) 
	{
		if(_machine == null)
			return;
		_machine.processUpdates(machine.getCurrentSpeed(), machine.getStatus(), machine.getOrder());
		setChanged();
		notifyObservers(this);
	}
	
	// this method should be called when something notable has changed in the holder that the view needs to know
	@Override
	public void notifyObservers() 
	{
		setChanged();
		super.notifyObservers(this);
	}
	
	
	public void notifyErrorToObservers(String error)
	{
		errorMessage = error;
		setChanged();
		notifyObservers();
	}
	
	// this method is called when you want to stop the update cycle manually
	public void stopThread()
	{
		if(_machineUpdateTimer != null)
		{
			_machineUpdateTimer.cancel();
			_machineUpdateTimer.purge();
			_machineUpdateTimer = null;
		}
		Log.d(TAG, String.format("STOP! HAMMERTIME!"));
	}
	
	// getters & setters
	public String getID()
	{
		return _id;
	}
	
	public Rect getSurface()
	{
		return _surface;
	}
	
	public void setMachine(Machine machine)
	{
		Log.e(TAG, String.format("machine! %s, %s, %s", machine.toString(), machine.getCurrentSpeed(), machine.getName()));
		this._machine = machine;
		errorMessage = "";
	}
	
	public Machine getMachine()
	{
		return _machine;
	}
	
	public void setSurface(Rect surface)
	{
		_surface = surface;
		setChanged();
		notifyObservers(this);
	}
}
